package NetWork;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 石方旭
 * Date: 2022-08-13
 * Time: 10:33
 */
public class UdpEchoServer {

    //1.接收客户端的请求
    //2.对客户端的请求进行解析
    //3.根据解析请求做出响应
    //4.将响应发送给客户端
    //5.将请求和响应的结果在服务器上显示

    //DatagramSocket用于接收和发送UDP数据报
    DatagramSocket socket = null;

    //port代表端口号==>端口号用于区别不同的进程==>通过端口号就知道发送给哪个进程
    //进行网络通信必须要端口号
    public UdpEchoServer(int port) throws SocketException {
        //创建DatagramSocket对象就相当于打开内核中的socket==>用来传输数据
        //此外又将其与端口关联起来==>用于告知将数据发送给哪个进程
        socket = new DatagramSocket(port);
        //==>这里要抛出SocketException
        //一个端口不能被不同的进程使用,如果使用就抛出异常
    }

    //这里是回显服务器,请求啥就返回啥
    public String process(String request){
        return request;
    }

    //接下来正式开启UDP服务器
    public void start() throws IOException {
        System.out.println("UDP服务器正式启动!!!");
        while(true){//服务器要长时间运行
            //读取客户端的请求==>使用receive来接收
            //receive接收需要将接受的数据放到数据报里
            //所以我们要创建一个请求数据报
            DatagramPacket requestPacket = new DatagramPacket(
                    new byte[4096],
                    4096);//==>将其数据报保存在缓存区byte里面并且指定长度
            //这里的receive如果没有接收到请求,就进行阻塞等待,一直等待客户端发来请求,然后进行接收
            socket.receive(requestPacket);//这里要处理输入输出异常=>防止有输入输出错误
            //我们接收到请求,接下来要进行解析请求==>构造为一个字符串
            String request = new String(requestPacket.getData(),0,
                    requestPacket.getLength());//==>将数据报的数据构造出字符串,构造0~length
            //我们解析完请求,要做出响应并返回
            String response = process(request);
            //再将响应构造成一个数据报返回去
            //将响应的数据放到响应数据报里,然后从哪里来就返回哪里去==>requestPacket的地址
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes()
            ,response.getBytes().length,requestPacket.getSocketAddress());
            //然后将数据发送给客户端
            socket.send(responsePacket);
            System.out.printf("[%s %d] request=%s; response=%s\n",requestPacket.getAddress().toString()
            ,requestPacket.getPort(),request,response);
        }
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer udpEchoServer = new UdpEchoServer(8000);
        udpEchoServer.start();
    }
}
